package com.tonyodev.fetch2;

import com.tonyodev.fetch2core.Downloader;

/**
 * Error
 *
 * @since 2021-05-20
 */
public enum Error {
    /**
     * Indicates that the specific issue or error is not known.
     */
    UNKNOWN(-1),

    /**
     * Indicates that no error has occurred. This is the default error for a download
     * when no errors have occurred.
     */
    NONE(0),

    /**
     * Indicates that Fetch was not able to create the file on disk. This may indicate
     * that the app does not have the proper read and write permissions.
     */
    FILE_NOT_CREATED(1),

    /**
     * Indicates that the connection has timed out.
     */
    CONNECTION_TIMED_OUT(2),

    /**
     * Indicates that the download client was not able to identify or find the host.
     * This may indicate that the url of a download may be bad.
     */
    UNKNOWN_HOST(3),

    /**
     * Indicates that the download client was not able to find the url.
     * This may indicate that the url of a download may be broken.
     */
    HTTP_NOT_FOUND(4),

    /**
     * Indicates that the app does not have proper read and write permissions.
     */
    WRITE_PERMISSION_DENIED(5),

    /**
     * Indicates that the device has no more storage space to continue the download.
     */
    NO_STORAGE_SPACE(6),

    /**
     * Indicates that the devices does not have an active internet connection.
     */
    NO_NETWORK_CONNECTION(7),

    /**
     * Indicates that an empty response was returned by the server.
     */
    EMPTY_RESPONSE_FROM_SERVER(8),

    /**
     * Indicates that Fetch was unable to enqueue a new request because the same request
     * already exist and is being managed.
     */
    REQUEST_ALREADY_EXIST(9),

    /**
     * Indicates that Fetch does not manage a download with the specified id.
     */
    DOWNLOAD_NOT_FOUND(10),

    /**
     * Indicates that a Fetch database error occurred.
     */
    FETCH_DATABASE_ERROR(11),

    /** Error 12 no longer needed by Fetch. removed*/

    /**
     * Indicates that a request in the Fetch database already has this unique id.
     * Ids must be unique.
     */
    REQUEST_WITH_ID_ALREADY_EXIST(13),

    /**
     * Indicates that a request in the Fetch database already has this file path. File Paths
     * have to be unique for each request. This limitation maintains consistency and prevents data lose.
     * Fetch cannot write data to two different downloads with the same file path.
     */
    REQUEST_WITH_FILE_PATH_ALREADY_EXIST(14),

    /**
     * Indicates that unsuccessful response was returned by the server.
     */
    REQUEST_NOT_SUCCESSFUL(15),

    /**
     * Indicates that an unknown IO issue occurred.
     */
    UNKNOWN_IO_ERROR(16),

    /**
     * Indicates that the file belonging to the request has been deleted. The file
     * could have been deleted by an external source.
     */
    FILE_NOT_FOUND(17),

    /**
     * Indicates that the request url is not a valid url to reach a Fetch File Server.
     */
    FETCH_FILE_SERVER_URL_INVALID(19),

    /**
     * Indicates that the downloaded file hash does not match the hash the server returned
     * for the content.
     */
    INVALID_CONTENT_HASH(20),

    /**
     * Indicates that Fetch was unable to update the existing request.
     */
    FAILED_TO_UPDATE_REQUEST(21),

    /**
     * Indicates that Fetch was unable to add a completed download.
     */
    FAILED_TO_ADD_COMPLETED_DOWNLOAD(22),

    /**
     * Indicates that the Fetch File Server returned the wrong response type.
     */
    FETCH_FILE_SERVER_INVALID_RESPONSE(23),

    /**
     * Indicates that the Request Being Queried does not exist.
     */
    REQUEST_DOES_NOT_EXIST(24),

    /**
     * Indicates that the Request was not enqueued.
     */
    ENQUEUE_NOT_SUCCESSFUL(25),

    /**
     * Indicates that the Completed download was not added successfully.
     */
    COMPLETED_NOT_ADDED_SUCCESSFULLY(26),

    /**
     * Indicates that the requests in the list are not distinct by file name.
     */
    ENQUEUED_REQUESTS_ARE_NOT_DISTINCT(27),

    /**
     * Indicates that the operation to rename the file for a download failed because
     * the download does not have a status of complete.
     */
    FAILED_TO_RENAME_INCOMPLETE_DOWNLOAD_FILE(28),

    /**
     * Indicates that the operation to rename the file failed for some reason.
     */
    FAILED_TO_RENAME_FILE(29),

    /**
     * Indicates that an error occurred when pre allocating the needed space on the storage system for the download.
     */
    FILE_ALLOCATION_FAILED(30),

    /**
     * Indicates that connection to "http" is not allowed by the OS and "https" is required.
     */
    HTTP_CONNECTION_NOT_ALLOWED(31);

    private int value;
    private Throwable throwable;
    private Downloader.Response httpResponse;

    /**
     * create instance
     *
     * @param value value
     */
    Error(int value) {
        this(value, null, null);
    }

    /**
     * create instance
     *
     * @param value value
     * @param throwable throwable
     */
    Error(int value, Throwable throwable) {
        this(value, throwable, null);
    }

    /**
     * create instance
     *
     * @param value value
     * @param throwable throwable
     * @param httpResponse httpResponse
     */
    Error(int value, Throwable throwable, Downloader.Response httpResponse) {
        this.value = value;
        this.throwable = throwable;
        this.httpResponse = httpResponse;
    }

    /**
     * get error value
     *
     * @return value
     */
    public int getValue() {
        return value;
    }

    /**
     * Throwable
     *
     * @return Throwable
     */
    public Throwable getThrowable() {
        return throwable;
    }

    /**
     * get Downloader.Response
     *
     * @return Downloader.Response
     */
    public Downloader.Response getHttpResponse() {
        return httpResponse;
    }

    /**
     * setThrowable
     *
     * @param throwable throwable
     */
    public void setThrowable(Throwable throwable) {
        this.throwable = throwable;
    }

    /**
     * setHttpResponse
     *
     * @param httpResponse httpResponse
     */
    public void setHttpResponse(Downloader.Response httpResponse) {
        this.httpResponse = httpResponse;
    }

    /**
     * Error
     *
     * @param value valueOf
     * @return valueOf
     */
    public static Error valueOf(int value) {
        switch (value) {
            case -1:
                return UNKNOWN;
            case 0:
                return NONE;
            case 1:
                return FILE_NOT_CREATED;
            case 2:
                return CONNECTION_TIMED_OUT;
            case 3:
                return UNKNOWN_HOST;
            case 4:
                return HTTP_NOT_FOUND;
            case 5:
                return WRITE_PERMISSION_DENIED;
            case 6:
                return NO_STORAGE_SPACE;
            case 7:
                return NO_NETWORK_CONNECTION;
            case 8:
                return EMPTY_RESPONSE_FROM_SERVER;
            case 9:
                return REQUEST_ALREADY_EXIST;
            case 10:
                return DOWNLOAD_NOT_FOUND;
            case 11:
                return FETCH_DATABASE_ERROR;
            case 13:
                return REQUEST_WITH_ID_ALREADY_EXIST;
            case 15:
                return REQUEST_NOT_SUCCESSFUL;
            case 16:
                return UNKNOWN_IO_ERROR;
            case 17:
                return FILE_NOT_FOUND;
            case 19:
                return FETCH_FILE_SERVER_URL_INVALID;
            case 20:
                return INVALID_CONTENT_HASH;
            case 21:
                return FAILED_TO_UPDATE_REQUEST;
            case 22:
                return FAILED_TO_ADD_COMPLETED_DOWNLOAD;
            case 23:
                return FETCH_FILE_SERVER_INVALID_RESPONSE;
            case 24:
                return REQUEST_DOES_NOT_EXIST;
            case 25:
                return ENQUEUE_NOT_SUCCESSFUL;
            case 26:
                return COMPLETED_NOT_ADDED_SUCCESSFULLY;
            case 27:
                return ENQUEUED_REQUESTS_ARE_NOT_DISTINCT;
            case 28:
                return FAILED_TO_RENAME_INCOMPLETE_DOWNLOAD_FILE;
            case 29:
                return FAILED_TO_RENAME_FILE;
            case 30:
                return FILE_ALLOCATION_FAILED;
            case 31:
                return HTTP_CONNECTION_NOT_ALLOWED;
            default:
                return UNKNOWN;
        }
    }
}
